package xyz.xiaoshengfu.xrpc.data;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.lang3.StringUtils;

import xyz.xiaoshengfu.xrpc.config.ProviderServiceInfor;

/**
 * <p>Title: XRpcWeightStrategy</p>
 * <p>Description: 权重负载均衡策略实现类</p>
 * @author xiaoshengfu(2439323118@qq.com)
 * @date 2020年3月26日
 */
public class XRpcWeightStrategy {

	private final List<ProviderServiceInfor> providerServiceInforList = new ArrayList<ProviderServiceInfor>();
	private int currentIndex = 0;
	private int residualTimes = 0;
	private final ReentrantLock lock = new ReentrantLock();

	public XRpcWeightStrategy() {
		super();
	}

	public ProviderServiceInfor weightStrategyGetProviderServiceInfor() {
		lock.lock();
		try {
			if (providerServiceInforList.size() > 0) {
				ProviderServiceInfor providerServiceInfor = providerServiceInforList.get(currentIndex);
				if (--residualTimes == 0) {
					if (currentIndex == providerServiceInforList.size() - 1) {
						currentIndex = 0;
					} else {
						currentIndex++;
					}
					residualTimes = providerServiceInforList.get(currentIndex).getServiceBean().getWeight();
				}
				return providerServiceInfor;
			}
			return null;
		} finally {
			lock.unlock();
		}
	}

	public void addProviderServiceInfor(ProviderServiceInfor providerServiceInfor) {
		if (providerServiceInforList.size() == 0 && residualTimes == 0) {
			residualTimes = providerServiceInfor.getServiceBean().getWeight();
		}
		for (int i = 0; i < providerServiceInforList.size(); i++) {
			if (providerServiceInforList.get(i).getApplicationName()
					.equals(providerServiceInfor.getApplicationName())) {
				providerServiceInforList.set(i, providerServiceInfor);
				return;
			}
		}
		providerServiceInforList.add(providerServiceInfor);
	}

	public void removeProviderServiceInfor(String applicationName) {
		lock.lock();
		try {
			if (StringUtils.isNoneBlank(applicationName)) {
				for (int i = 0; i < providerServiceInforList.size(); i++) {
					if (providerServiceInforList.get(i).getApplicationName().equals(applicationName)) {
						providerServiceInforList.remove(i--);
					}
				}
			}
			currentIndex = 0;
			if (providerServiceInforList.size() == 0) {
				residualTimes = 0;
			} else {
				residualTimes = providerServiceInforList.get(0).getServiceBean().getWeight();
			}
		} finally {
			lock.unlock();
		}
	}

	public List<ProviderServiceInfor> getProviderServiceInforList() {
		return providerServiceInforList;
	}
}
